<?php


/**
 * GD库验证码
 *
 * the last known user to change this file in the repository  <$LastChangedBy: gao.wanggao $>
 *
 * @author $Author: gao.wanggao $ foxsee@aliyun.com
 *
 * @version $Id: PwGDCode.php 23362 2013-01-09 04:19:41Z gao.wanggao $
 */
class PwGDCode extends PwBaseCode
{
    private static $_background;

    private static $_graph;

    private static $_font;

    private static $_size;

    private static $_angle;

    private static $_color;

    private static $_codeLen = 0;

    private static $_codeX = 0;

    private static $_codeY = 0;

    private static $_image;

    public static function init()
    {
        if (!function_exists('imagecreatetruecolor') && !function_exists('imagecolorallocate') && !function_exists('imagestring') && !function_exists('imagepng') && !function_exists('imagesetpixel') && !function_exists('imagefilledrectangle') && !function_exists('imagerectangle')) {
            return false;
        }
        self::setRandCode();

        return true;
    }

    public static function outputImage()
    {
        return self::$isRandGif ? (self::_outGif()) : (self::_outPng());
    }

    public static function outputFlash()
    {
        return self::_outFlash();
    }

    private static function _setRandX()
    {
        self::$_codeX = floor((self::$verifyWidth - 20) / self::$_codeLen);
    }

    private static function _setRandY()
    {
        $_y = self::$verifyHeight / 2;
        self::$_codeY = mt_rand($_y + 5, $_y + 10);
    }

    private static function _setRandBackground()
    {
        $red = self::$isRandBackground ? mt_rand(100, 200) : 255;
        $green = self::$isRandBackground ? mt_rand(100, 200) : 255;
        $blue = self::$isRandBackground ? mt_rand(100, 200) : 255;
        $alpha = 0; //self::$isRandBackground ? mt_rand(0, 127) : 0;
        self::$_background = array('red' => $red, 'green' => $green, 'blue' => $blue, 'alpha' => $alpha);
    }

    private static function _setPicBackground()
    {
        $bgs = self::getVerifyBackground();
        $rand = array_rand($bgs);
        $imbg = imagecreatefromjpeg($bgs[$rand]);
        if (!$imbg) {
            return false;
        }
        imagecopymerge(self::$_image, $imbg, 0, 0, mt_rand(0, 450 - self::$verifyWidth), mt_rand(0, 150 - self::$verifyHeight), self::$verifyWidth, self::$verifyHeight, 100);
        imagedestroy($imbg);
    }

    private static function _setRandFont()
    {
        $_path = Wind::getRealDir(self::$path.'.font');
        if (self::$verifyType < 5) {
            $_fontList = self::getEnFontList();
        } else {
            $_fontList = self::getCnFontList();
        }
        $key = self::$isRandFont ? array_rand($_fontList, 1) : 0;
        self::$_font = $_path.'/'.$_fontList[$key];
    }

    private static function _setRandSize()
    {
        self::$_size = self::$isRandSize ? mt_rand(14, 20) : 18;
    }

    private static function _setRandAngle()
    {
        self::$_angle = self::$isRandAngle ? mt_rand(-20, 10) : 0;
    }

    private static function _setRandColor()
    {
        if (!self::$isRandColor) {
            self::$_color = imagecolorallocate(self::$_image, 0, 0, 0);
        } else {
            self::$_color = imagecolorallocate(self::$_image, mt_rand(0, 255), mt_rand(0, 120), mt_rand(0, 255));
        }
    }

    private static function _setRandDistortion()
    {
        if (!self::$isRandDistortion) {
            return true;
        }
        $_tmp = self::$_image;
        self::$verifyWidth = self::$verifyWidth;
        self::_creatImage();
        self::_creatBackground();
        for ($i = 0; $i < self::$verifyWidth; $i++) {
            for ($j = 0; $j < self::$verifyHeight; $j++) {
                $_color = imagecolorat($_tmp, $i, $j);
                if (intval($i + sin($j / self::$verifyHeight * 2 * M_PI) * 10) <= self::$verifyWidth && intval(($i + sin($j / self::$verifyHeight * 2 * M_PI) * 10)) >= 0) {
                    imagesetpixel(self::$_image, intval($i + sin($j / self::$verifyHeight * 2 * M_PI - 0.6) * 5), $j, $_color);
                }
            }
        }
    }

    private static function _setRandGraph()
    {
        if (!self::$isRandGraph) {
            return true;
        }
        $_tmp = mt_rand(1, 3);
        switch ($_tmp) {
            case '1':
                self::_setImageLine();
                break;
            case '2':
                self::_setImagePix();
                break;
            case '3':
                self::_setImageEarc();
                break;
           /* case '4':
                self::_setImageLine();
                   self::_setImageEarc();
                break;
            case '5':
                   self::_setImageLine();
                   //self::_setImagePix();
                break;
            case '6':
                   //self::_setImagePix();
                   self::_setImageEarc();
                break;*/
        }
    }

    private static function _setImageLine()
    {
        $_tmp = mt_rand(30, 40);
        for ($i = 0; $i < $_tmp; $i++) {
            $_x = mt_rand(0, self::$verifyWidth);
            $_y = mt_rand(0, self::$verifyHeight);
            $_color = imagecolorallocate(self::$_image, mt_rand(50, 255), mt_rand(50, 200), mt_rand(25, 200));
            imageline(self::$_image, $_x, $_y, mt_rand(($_x - 10), ($_x + 5)), mt_rand(($_y + 5), ($_y + 20)), $_color);
        }
    }

    private static function _setImagePix()
    {
        $_tmp = mt_rand(600, 800);
        for ($i = 0; $i < $_tmp; $i++) {
            $_color = imagecolorallocate(self::$_image, mt_rand(50, 255), mt_rand(50, 200), mt_rand(25, 200));
            imagesetpixel(self::$_image, mt_rand(0, self::$verifyWidth), mt_rand(0, self::$verifyHeight), $_color);
        }
    }

    private static function _setImageEarc()
    {
        $_tmp = mt_rand(5, 10);
        for ($i = 0; $i < $_tmp; $i++) {
            $_color = imagecolorallocate(self::$_image, mt_rand(50, 255), mt_rand(50, 200), mt_rand(25, 200));
            imagearc(self::$_image, mt_rand(0, self::$verifyWidth), mt_rand(10, self::$verifyHeight), mt_rand(10, self::$verifyWidth), mt_rand(self::$verifyHeight, self::$verifyHeight * 2), mt_rand(0, 90), mt_rand(0, 90), $_color);
        }
    }

    private static function _getCodeLenth()
    {
        //self::$_codeLen = Pw::strlen(self::$verifyCode);
        self::$_codeLen = WindString::strlen(self::$verifyCode, 'utf-8');
    }

    private static function _outFlash()
    {
        if (!class_exists('SWFBitmap')) {
            return false;
        }
        self::_getCodeLenth();
        self::_creatImage();
        self::_setRandBackground();
        self::_creatBackground();
        //self::_setPicBackground();
        self::_setRandFont();
        self::_setRandGraph();
        self::_writeImage();
        self::_setRandDistortion();
        $_tmpPath = Wind::getRealDir('DATA:tmp.');
        $_tmp = $_tmpPath.WindUtility::generateRandStr(8).'.png';
        imagepng(self::$_image, $_tmp);
        if (!WindFile::isFile($_tmp)) {
            return false;
        }
        imagedestroy(self::$_image);
        $bit = new SWFBitmap($_tmp);
        $shape = new SWFShape();
        $shape->setRightFill($shape->addFill($bit));
        $shape->drawLine($bit->getWidth(), 0);
        $shape->drawLine(0, $bit->getHeight());
        $shape->drawLine(-$bit->getWidth(), 0);
        $shape->drawLine(0, -$bit->getHeight());
        $movie = new SWFMovie();
        $movie->setDimension($bit->getWidth(), $bit->getHeight());
        $flash = $movie->add($shape);
        header('Pragma:no-cache');
        header('Cache-control:no-cache');
        header('Content-type: application/x-shockwave-flash');
        $movie->output();
        WindFolder::clear($_tmpPath);
    }

    private static function _outPng()
    {
        header('Pragma:no-cache');
        header('Cache-control:no-cache');
        header('Content-type: image/png');
        self::_getCodeLenth();
        self::_creatImage();
        if (self::$isRandBackground) {
            self::_setPicBackground();
        } else {
            self::_setRandBackground();
            self::_creatBackground();
        }
        self::_setRandFont();
        self::_setRandGraph();
        self::_writeImage();
        self::_setRandDistortion();
        imagepng(self::$_image);
        imagedestroy(self::$_image);
    }

    private static function _outGif()
    {
        header('Pragma:no-cache');
        header('Cache-control:no-cache');
        header('Content-type: image/gif');

        self::_getCodeLenth();
        self::_setRandBackground();
        self::_setRandFont();
        for ($i = 0; $i < 3; $i++) {
            self::_creatImage();
            self::_creatBackground();
            self::_setRandGraph();
            self::_writeImage();
            ob_start();
            imagegif(self::$_image);
            $frame[] = ob_get_contents();
            $delay[] = 100;
            imagedestroy(self::$_image);
            ob_end_clean();
        }
        $gif = new GifMerge($frame, 0, 0, 0, 0, $delay, 0, 0, 'C_MEMORY');
        echo $gif->getAnimation();
    }

    private static function _writeImage()
    {
        for ($i = 0; $i < self::$_codeLen; $i++) {
            //$_text = Pw::substrs(self::$verifyCode, 1, $i, false);
            $_text = WindString::substr(self::$verifyCode, $i, 1, 'utf-8', false);
            self::_setRandSize();
            self::_setRandAngle();
            self::_setRandX();
            self::_setRandY();
            self::_setRandColor();
            imagettftext(self::$_image, self::$_size, self::$_angle, (self::$_codeX * $i + 10), self::$_codeY, self::$_color, self::$_font, $_text);
        }
    }

    private static function _creatImage()
    {
        self::$_image = imagecreatetruecolor(self::$verifyWidth, self::$verifyHeight);
        imagesavealpha(self::$_image, true);
    }

    private static function _creatBackground()
    {
        $_tmp = imagecolorallocatealpha(self::$_image, self::$_background['red'], self::$_background['green'], self::$_background['blue'], self::$_background['alpha']);
        imagefill(self::$_image, 20, 0, $_tmp);
    }
}
